<?php
/****************************************************************************
* imageTransform.php v 1.3.5
*
* v 1.3.5
*
* This script allow to resize yours JPG, PNG or GIF images
* You can reduce or enlarge the images size maintaining its proportions
* You can crop the image with your desired size also maintaining its proportions
*
* Example:
*
* Reduce 800x600 image:
*
* $imageTransform->resize('car.jpg', 500, 500);
*
* The result is the image image resized to 500x375 (maintaining proportions)
*
* ----------------------------------------------------------------
*
* Create a resized thumb from a 800x600 image:
*
* $imageTransform->resize('car.jpg', 500, 500, 'tb_car.jpg');
*
* The result is a new image with sizes 500x375
*
* ----------------------------------------------------------------
*
* Cut 800x600 image:
*
* $imageTransform->crop('car.jpg', 500, 500);
*
* The result is the image image crop to 500x500 (first reduction, then crop)
*
* ----------------------------------------------------------------
*
* Create a crop image from a 800x600 image:
*
* $imageTransform->crop('car.jpg', 500, 500, 'tb_car.jpg');
*
* The result is a new image with size 500x500
*
* ----------------------------------------------------------------
*
* Create a flip vertical or flop horizontal image:
*
* $imageTransform->flipflop('car.jpg', 'flip', 'tb_car.jpg');
*
* The result is a new image with vertical flip
*
* $imageTransform->flipflop('car.jpg', 'flop', 'tb_car.jpg');
*
* The result is a new image with horizontal flop
*
* $imageTransform->flipflop('car.jpg', 'flipflop', 'tb_car.jpg');
*
* The result is a new image with vertical and horizontal flipflop
*
* ----------------------------------------------------------------
*
* Create a grayscale image (slow function):
*
* $imageTransform->gray('car.jpg', 'tb_car.jpg');
*
* The result is a new grayscale image
*
* ----------------------------------------------------------------
*
* Change image quality:
*
* $imageTransform->quality('car.jpg', 70);
*
* ----------------------------------------------------------------
*
* You also can use this class into an online image transformation.
*
* You can find examples in the view.php script (with this package)
*

* KNOWN BUGS:

* Bad transparency when resize/crop some GIF images
* Bad transparency when rotate some GIF images
* Bad transparency when grayscale some GIF and PNG images
*
* working around...

First publish: http://www.phpclasses.org/browse/package/4268.html

Copyright (C) 2008 Lito <lito@eordes.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

SEE HERE FOR MORE ==>> http://www.gnu.org/copyleft/gpl.html
*******************************************************************************/

class img_lib {
    var $image;
    var $target;
    var $size;
    var $debug = true; // Show errors
    var $quality = 80; // Result image quality
//    var $cache = 'cache/'; // Cache folder
    var $cache = false; // Cache disabled
    var $expire = 172800; // Cache expiration time in seconds
    var $enlarge = true; // Enlarge image if width or height needed is bigger than original
    var $data = array(); // Image data array
    var $forceType = false; // Force image type create
    var $allowed = array( // Valid image formats
        1 => 'gif',
        2 => 'jpg',
        3 => 'png'
    );

  /**
  * Created by Bryan Jayson Tan
  * Date: June 02, 2010
  * GETTER SETTER METHOD, SOME VALUE HAS ALREADY GETTER SETTER PLEASE LOOK FURTHER
  **/
  function setDebug($v)
  {
    $this->debug = $v;
  }
  function setQuality($v)
  {
    $this->quality = $v;
  }
  function setExpire($v)
  {
    $this->expire = $v;
  }
  
    /**
    * function debug (string $message)
    *
    * Print the error messages
    */
    function debug ($message) {
        if ($this->debug) {
            $debug = debug_backtrace();

            rsort($debug);

            echo $message;

            foreach ($debug as $k => $v) {
                echo "\n\n".'<br /><br />'.str_repeat('&nbsp;', (2 + $k * 2)).'FILE: '.$v['file'];
                echo "\n".'<br />'.str_repeat('&nbsp;', (2 + $k * 2)).'LINE: '.$v['line'];
            }

            echo "\n".'<br />';
        }

        return false;
    }

    /**
    * function enlarge (boolean $value)
    *
    * When you resize or crop an image, you need the width and height
    * You can disable enlarge an image if the original size is lower than
    * the needed width and height
    */
    function enlarge ($value) {
        $this->enlarge = $value;
    }

    /**
    * function forceType (integer $type)
    *
    * Force to generate the new image with a concrete type
    *
    * (1 => GIF, 2 => JPEG, 3 => PNG)
    */
    function forceType ($type) {
        $this->forceType = $type;
    }

    /**
    * function itsImage (string $image)
    *
    * Check if it's a valid image
    *
    * return false:array
    */
    function itsImage ($image) {
        if ($data = @getImageSize($image)) {
            return empty($this->allowed[$data[2]])?false:$data;
        } else {
            return false;
        }
    }

  // Created by Bryan Jayson Tan
  // Created at: July 30, 2010
  public function getExt($filename)
  {
    $filename = strtolower($filename) ; 
    $exts = split("[/\\.]", $filename) ; 
    $n = count($exts)-1; 
    $exts = $exts[$n]; 
    
    foreach($this->allowed as $allow){
      if ($allow == $exts){
        return $exts;
      }
    }
    return false;

  }
  
    /**
    * function cache (string $value)
    *
    * Enable/disable the image cache
    * To enable cache, needs the folder cache path
    */
    function cache ($value) {
        if ($value === false) {
            $this->cache = false;
        } elseif (($value === true) && (empty($this->cache) || ($this->cache === true) || ($this->cache === false))) {
            $this->cache = false;
            
            $this->debug('The cache folder haven\'t a valid path: '.$this->cache);
        } elseif (!is_dir($value) || !is_writable($value)) {
            $this->cache = false;

            $this->debug('The cache folder isn\'t writable to me: '.$value);
        } else {
            $this->cache = preg_match('#/$#', $value)?$value:($value.'/');
        }
    }

    /**
    * function inlineHeaders (string $name)
    *
    * Print the inline headers to view function
    */
    function inlineHeaders ($name) {
        header('Content-type: image/'.$this->allowed[$this->data[2]]);
        header('Content-Disposition: inline; filename="'.$name.'"');
    }

    /**
    * function view (string $mode, string $param, boolean $cache = true)
    *
    * View online an resize/crop image. The image result can be cached.
    */
    function view ($mode, $image, $param, $cache = true) {
        if (!($this->data = $this->itsImage($image))) {
            return $this->debug($image.' isn\'t a valid image');
        }

        $name = explode('/', $image);
        $name = end($name);
        $ext = explode('.', $name);
        $ext = strtolower(end($ext));

        if (($mode == 'resize') || ($mode == 'crop')) {
            list($width, $height) = explode('x', $param);

            $width = intval($width);
            $height = intval($height);

            if (($width <= 0) || ($height <= 0)) {
                return $this->debug('No size valid: '.$width.'x'.$height);
            }

            if ((($this->enlarge == false) && ($this->data[0] <= $width) && ($this->data[1] <= $height))
            || (($this->data[0] == $width) && ($this->data[1] == $height))) {
                $this->inlineHeaders($name);

                echo file_get_contents($image);

                return true;
            }
        }

        if ($cache && $this->cache) {
            if (!$this->recursive_path($this->cache) || !is_writable($this->cache)) {
                return $this->debug('Can\'t write in the cahe folder: '.$this->cache);
            }

            $target = $this->cache.md5($mode.'x'.$image.'x'.$param).'.'.$ext;

            if (is_file($target) && (filemtime($target) > (time() - $this->expire))) {
                $this->inlineHeaders($name);

                echo file_get_contents($target);

                return true;
            }
        } else {
            $target = false;
        }

        $this->inlineHeaders($name);

        switch($mode) {
            case 'gray':
                $ok = $this->gray($image, $target, true);
                break;
            case 'rotate':
                $ok = $this->rotate($image, $param, $target, true);
                break;
            case 'resize':
            case 'crop':
                $ok = $this->$mode($image, $width, $height, $target, true);
                break;
            case 'flip':
            case 'flop':
            case 'flipflop':
                $ok = $this->flipflop($image, $mode, $target, true);
                break;
            default:
                return $this->debug($mode.' isn\'t a valid mode');
        }

        if ($target == false) {
            return $ok;
        } elseif ($ok == true) {
            echo file_get_contents($target);
        } else {
            return false;
        }
    }

    /**
    * function defineTarget (string $thumb, boolean $view)
    *
    * Assign a valid value to target image
    *
    * return boolean
    */
    function defineTarget ($thumb, $view) {
        if ($view) {
            $this->target = $thumb?$thumb:false;
        } elseif (empty($thumb)) {
            if (!is_writable($this->image)) {
                return $this->debug('The original image haven\'t write permissions to me: '.$this->image);
            }

            $this->target = $this->image;
        } else {
            $this->target = $thumb;
            $folder = (dirname($this->target) == '')?'./':dirname($this->target);

            if (!$this->recursive_path($folder) || !is_writable($folder)) {
                return $this->debug('Can\'t write in the target folder: '.$folder);
            }
        }

        return true;
    }

    /**
    * function gray (string $image, string $thumb = '', string $view = false)
    *
    * Transform an image to grayscale
    *
    * If the parameter $thumb it's set, instead transform the image image,
    * create a new with the location in set.
    *
    * $view condition is used in the online image view funcion
    *
    * return boolean
    */
    function gray ($image, $thumb = '', $view = false) {
        if (!($this->data = $this->itsImage($image))) {
            return $this->debug($image.' isn\'t a valid image');
        }

        $this->image = $image;

        $this->defineTarget($thumb, $view);

        $thumb = $this->imageDefine();

        $quality = true;

        if ($quality) {
            // More slower but best quality

            for ($c = 0; $c < 256; $c++) {
                $palette[$c] = imageColorAllocate($thumb, $c, $c, $c);
            }

            for ($x = 0; $x < $this->data[0]; $x++) {
                for ($y = 0; $y < $this->data[1]; $y++) {
                    $gray = (ImageColorAt($thumb, $x, $y) >> 8) & 0xFF;
                    $rgb = imagecolorat($thumb, $x, $y);
                    $r = ($rgb >> 16) & 0xFF;
                    $g = ($rgb >> 8) & 0xFF;
                    $b = $rgb & 0xFF;

                    $gs = ($r * 0.299) + ($g * 0.587) + ($b * 0.114);

                    imagesetpixel($thumb, $x, $y, $palette[$gs]);
                }
            }
        } else {
            // More faster but less quality

            for ($x = 0; $x < $this->data[0]; $x++) {
                for ($y = 0; $y < $this->data[1]; $y++) {
                    $gray = (ImageColorAt($thumb, $x, $y) >> 8) & 0xFF;

                    imagesetpixel($thumb, $x, $y, imageColorAllocate($thumb, $gray,$gray,$gray));
                }
            }
        }

        if ($this->imageCreate($thumb)) {
            return true;
        } else {
            return $this->debug('A problem occours creating the image. I can\'t finish the task.');
        }
    }

    /**
    * function resize (string $image, integer $width, integer $height, string $thumb = '', boolean $view = false)
    *
    * This function resize an image maintaining the image proportions.
    *
    * If the parameter $thumb it's set, instead transform the image image,
    * create a new with the location in set.
    *
    * $whith and $height set the max sizes allowed to width and height, not set the
    * sizes in the result image, the result sizes are calculated with this values.
    *
    * $view condition is used in the online image view funcion
    *
    * return boolean
    */
  
  // copy the original image
  function copyImage($image, $thumb = '') {
        if (!($this->data = $this->itsImage($image))) {
            return $this->debug($image.' isn\'t a valid image');
        }

    if (($thumb != '')) {
      if ($this->defineTarget($thumb, false)) {
        @copy($image, $thumb);
      } else {
        return false;
      }
    }

    }
  
    function resize ($image, $width, $height, $thumb = '', $view = false) {
        if (!($this->data = $this->itsImage($image))) {
            return $this->debug($image.' isn\'t a valid image');
        }

        if ((($this->enlarge == false) && ($this->data[0] <= $width) && ($this->data[1] <= $height))
        || (($this->data[0] == $width) && ($this->data[1] == $height))) {
            if (($thumb != '') && ($image != $thumb)) {
                if ($this->defineTarget($thumb, false)) {
                    @copy($image, $thumb);
                } else {
                    return false;
                }
            }

            return true;
        }

        $this->image = $image;
        $this->size = array($width, $height);

        $this->defineTarget($thumb, $view);

        return $this->_mainTransform();
    }

    /**
    * function flip (string $image, string $mode, string $thumb = '', boolean $view = false)
    *
    * This function create and vertical flip or horizontal flop image.
    *
    * If the parameter $thumb it's set, instead transform the image image,
    * create a new with the location in set.
    *
    * $view condition is used in the online image view funcion
    *
    * return boolean
    */
    function flipflop ($image, $mode, $thumb = '', $view = false) {
        if (!($this->data = $this->itsImage($image))) {
            return $this->debug($image.' isn\'t a valid image');
        }

        $this->image = $image;

        $this->defineTarget($thumb, $view);

        $newImage = $this->imageDefine();

        $w = $this->data[0];
        $h = $this->data[1];
        $thumb = $this->transparency($newImage, imageCreateTrueColor($w, $h));

        if ($mode == 'flip') {
            for ($x = 0; $x < $w; $x++) {
                //imagecopy($thumb, $newImage, $x, 0, $w - $x - 1, 0, 1, $h); // Little more slow
                imagecopy($thumb, $newImage, $w - $x - 1, 0, $x, 0, 1, $h);
            }
        } elseif ($mode == 'flop') {
            for ($x = 0; $x < $h; $x++) {
                //imagecopy($thumb, $newImage, 0, $x, 0, $h - $x - 1, $w, 1); // Little more slow
                imagecopy($thumb, $newImage, 0, $h - $x - 1, 0, $x, $w, 1);
            }
        } else {
            for ($x = 0; $x < $w; $x++) {
                imagecopy($thumb, $newImage, $w - $x - 1, 0, $x, 0, 1, $h);
            }

            $buffer = $this->transparency($newImage, imageCreateTrueColor($w, 1));

            for ($y = 0; $y < ($h / 2); $y++) {
                imagecopy($buffer, $thumb, 0, 0, 0, $h - $y - 1, $w, 1);
                imagecopy($thumb, $thumb, 0, $h - $y - 1, 0, $y, $w, 1);
                imagecopy($thumb, $buffer, 0, $y, 0, 0, $w, 1);
            }

            imagedestroy($buffer);
        }

        if ($this->imageCreate($thumb)) {
            return true;
        } else {
            return $this->debug('A problem occours creating the image. I can\'t finish the task.');
        }
    }

    /**
    * function quality (string $image, integer $quality, string $thumb = '', boolean = boolean)
    *
    * Create or change one image with different quality
    *
    * return boolean
    */

    function quality ($image, $quality, $thumb = '', $view = false) {
        if (!($this->data = $this->itsImage($image))) {
            return $this->debug($image.' isn\'t a valid image');
        }

        $this->image = $image;

        $this->defineTarget($thumb, $view);

        $newImage = $this->imageDefine();

        $thumb = $this->transparency($newImage, imageCreateTrueColor($this->data[0], $this->data[1]));

        imagecopy($thumb, $newImage, 0, 0, 0, 0, $this->data[0], $this->data[1]);

        $old_quality = $this->quality;

        $this->quality = intval($quality);

        if ($this->forceType !== false) {
            $this->data[2] = $this->forceType;
        }

        $ok = $this->imageCreate($thumb);

        $this->quality = $old_quality;

        if ($ok) {
            return true;
        } else {
            return $this->debug('A problem occours creating the image. I can\'t finish the task.');
        }
    }

    /**
    * function crop (string $image, integer $width, integer $height, string $thumb = '', boolean $view = false)
    *
    * Cut the image with the desired size. First the image is reduced or enlarged and after it's crop.
    *
    * If the parameter $thumb it's set, instead transform the image image,
    * create a new with the location in set.
    *
    * $view condition is used in the online image view funcion
    *
    * return boolean
    */
    function crop ($image, $width, $height, $thumb = '', $view = false) {
        if (!($this->data = $this->itsImage($image))) {
            return $this->debug($image.' isn\'t a valid image');
        }

        if ((($this->enlarge == false) && ($this->data[0] <= $width) && ($this->data[1] <= $height))
        || (($this->data[0] == $width) && ($this->data[1] == $height))) {
            if (($thumb != '') && ($image != $thumb)) {
                if ($this->defineTarget($thumb, false)) {
                    @copy($image, $thumb);
                } else {
                    return false;
                }
            }

            return true;
        }

        $this->image = $image;
        $this->size = array($width, $height);

        $this->defineTarget($thumb, $view);

        if ($width == $height) {
            $less = ($this->data[0] > $this->data[1]) ? $this->data[1] : $this->data[0];
            $width = $height = $less;
            $posX = intval(($this->data[0] / 2) - ($less / 2));
            $posY = intval(($this->data[1] / 2) - ($less / 2));
        } elseif ($width > $height) {
            list($height, $width, $posX, $posY) = $this->cropSize($this->data[1], $this->data[0], $height, $width);

            if ($posY < 0) {
                list($width, $height, $posY, $posX) = $this->cropSize($this->data[0], $this->data[1], $this->size[0], $this->size[1]);
            }
        } elseif ($width < $height) {
            list($width, $height, $posY, $posX) = $this->cropSize($this->data[0], $this->data[1], $width, $height);

            if ($posX < 0) {
                list($height, $width, $posX, $posY) = $this->cropSize($this->data[1], $this->data[0], $this->size[1], $this->size[0]);
            }
        }

        return $this->_mainTransform($posX, $posY, $width, $height, false);
    }

    /**
    * function cropSize (integer $sourceX, integer $sourceY, integer $targetX, integer $targetY)
    *
    * Calculate the size and coords to the crop action
    *
    * return array
    */
    function cropSize ($sourceX, $sourceY, $targetX, $targetY) {
        $sizeX = round(($sourceX * $targetX) / (($sourceX * $targetY) / $sourceY));
        $sizeY = $sourceY;
        $coordX = 0;
        $coordY = intval(($sourceX / 2) - ($sizeX / 2));

        return array($sizeX, $sizeY, $coordX, $coordY);
    }

    /**
    * function rotate (string $image, integer $degrees, string $thumb = '', boolean $view = false)
    *
    * Rotate an image
    *
    * return boolean
    */
    function rotate ($image, $degrees, $thumb = '', $view = false) {
        if (!($this->data = $this->itsImage($image))) {
            return $this->debug($image.' isn\'t a valid image');
        }

        $this->image = $image;

        $this->defineTarget($thumb, $view);

        $newImage = $this->imageDefine();

        if (function_exists('imagerotate')) {
            $thumb = $this->transparency($newImage, imagerotate($newImage, $degrees, 0));
        } else {
            $src_x = imagesx($newImage);
            $src_y = imagesy($newImage);

            if ($degrees == 180) {
                $dest_x = $src_x;
                $dest_y = $src_y;
            } elseif ($src_x <= $src_y) {
                $dest_x = $src_y;
                $dest_y = $src_x;
            } elseif ($src_x >= $src_y) {
                $dest_x = $src_y;
                $dest_y = $src_x;
            }

            $thumb = $this->transparency($newImage, imageCreateTrueColor($dest_x, $dest_y));

            imagealphablending($thumb, false);

            switch ($degrees) {
                case 270:
                    for ($y = 0; $y < ($src_y); $y++) {
                        for ($x = 0; $x < ($src_x); $x++) {
                            $color = imagecolorat($newImage, $x, $y);
                            imagesetpixel($thumb, $dest_x - $y - 1, $x, $color);
                        }
                    }

                    break;
                case 90:
                    for ($y = 0; $y < ($src_y); $y++) {
                        for ($x = 0; $x < ($src_x); $x++) {
                            $color = imagecolorat($newImage, $x, $y);
                            imagesetpixel($thumb, $y, $dest_y - $x - 1, $color);
                        }
                    }

                    break;
                case 180:
                    for ($y = 0; $y < ($src_y); $y++) {
                        for ($x = 0; $x < ($src_x); $x++) {
                            $color = imagecolorat($newImage, $x, $y);
                            imagesetpixel($thumb, $dest_x - $x - 1, $dest_y - $y - 1, $color);
                        }
                    }

                    break;
                default:
                    $thumb = $newImage;
            }
        }

        if ($this->imageCreate($thumb)) {
            return true;
        } else {
            return $this->debug('A problem occours creating the image. I can\'t finish the task.');
        }
    }

    /**
    * function _mainTransform (integer $posX=0, integer $posY=0, integer $width=0, integer $height=0, boolean $proportions = true)
    *
    * Process the image transform
    *
    * return boolean
    */
    function _mainTransform ($posX=0, $posY=0, $width=0, $height=0, $proportions = true) {
        $newImage = $this->imageDefine();

        if (!$newImage) {
            return $this->debug($this->image.' isn\'t JPG, GIF nor PGN');
        }

        if ($proportions) {
            list($dX, $dY) = $this->proportions($this->data[0], $this->data[1]);
            list($width, $height) = array($this->data[0], $this->data[1]);
        } else {
            list($dX, $dY) = array($this->size[0], $this->size[1]);
        }

        list($posX, $posY) = $this->maxSize($posX, $posY, $width, $height);

        $thumb = $this->transparency($newImage, imageCreateTrueColor($dX, $dY));

        imageCopyResampled($thumb, $newImage, 0, 0, $posX, $posY, $dX, $dY, $width, $height);
        
        if ($this->imageCreate($thumb)) {
            return true;
        } else {
            return $this->debug('A problem occours creating the image. I can\'t finish the task.');
        }
    }

    /**
    * function imageDefine (void)
    *
    * Check the image format and create a new image with the same format
    *
    * return resource
    */
    function imageDefine () {
        switch ($this->data[2]) {
            case 1:
                return imageCreateFromGIF($this->image);
            case 2:
                return imageCreateFromJPEG($this->image);
            case 3:
                return imageCreateFromPNG($this->image);
            default:
                return false;
        }
    }

    /**
    * function imageCreate (resource $thumb)
    *
    * Create a new image from the $thumb resource
    *
    * return booelan
    */
    function imageCreate ($thumb) {
        if ($this->data[2] == 1) {
            $ok = imageGIF($thumb, $this->target, $this->quality);
        } elseif ($this->data[2] == 3) {
            $quality = 10 - round($this->quality / 10);
            $quality = (($quality < 0)?0:(($quality > 9)?9:$quality));

            $ok = imagePNG($thumb, $this->target, $quality);
        } else {
            $ok = imageJPEG($thumb, $this->target, $this->quality);
        }

        if ($ok) {
            imageDestroy($thumb);

            return true;
        } else {
            return false;
        }
    }

    /**
    * function transparency (resource $original, resource $new)
    *
    * Check and aply the transparency to an image
    *
    * return resource
    */
    function transparency ($original, $new) {
        if (($this->data[2] !== 1) && ($this->data[2] !== 3)) {
            return $new;
        }

        $trans_index = imagecolortransparent($original);

        if ($trans_index >= 0) {
            $trans_color = imagecolorsforindex($original, $trans_index);
            $trans_index = imagecolorallocate($new, $trans_index['red'], $trans_index['green'], $trans_index['blue']);

            imagefill($new, 0, 0, $trans_index);
            imagecolortransparent($new, $trans_index);
        } else if ($this->data[2] === 3) {
            imagealphablending($new, false);

            $colorTransparent = imagecolorallocatealpha($new, 0, 0, 0, 127);

            imagefill($new, 0, 0, $colorTransparent);
            imagesavealpha($new, true);
        }

        return $new;
    }

    /**
    * function proportions (integer $width, integer $height)
    *
    * Calculate the image proportions to a scalable image
    *
    * return array
    */
    function proportions ($width, $height) {
        if ($width > $height) {
            $n_width = $this->size[0];
            $n_height = round(($n_width * $height) / $width);
        } elseif ($height > $width) {
            $n_height = $this->size[1];
            $n_width = round(($n_height * $width) / $height);
        } elseif ($this->size[0] > $this->size[1]) {
            $n_width = $this->size[1];
            $n_height = $this->size[1];
        } else {
            $n_width = $this->size[0];
            $n_height = $this->size[0];
        }

        if ($n_width > $this->size[0]) {
            $n_width = $this->size[0];
            $n_height = round(($n_width * $height) / $width);
        }

        if ($n_height > $this->size[1]) {
            $n_height = $this->size[1];
            $n_width = round(($n_height * $width) / $height);
        }

        return array($n_width,$n_height);
    }

    /**
    * function maxSize (integer $posX, integer $posY, integer $width, integer $height)
    *
    * Calculate the image position from the image area
    *
    * return array
    */
    function maxSize ($posX, $posY, $width, $height) {
        $posX = (($posX + $width) > $this->data[0])?($this->data[0] - $width):$posX;
        $posX = ($posX < 0)?0:$posX;
        $posY = (($posY + $height) > $this->data[1])?($this->data[1] - $height):$posY;
        $posY = ($posY < 0)?0:$posY;
        
        return array($posX,$posY);
    }

    /**
    * function recursive_path (string $target)
    *
    * Create a recursive folder
    *
    * return boolean
    */
    function recursive_path ($target) {
        if (is_dir($target)) {
            return true;
        }

        $dirs = explode('/', $target);
        $dir = '';

        foreach ($dirs as $part) {
            if (empty($part) || ($part == '.')) {
                continue;
            }

            $dir .= '/'.$part;

            if (($part == '..') || is_dir($dir)) {
                continue;
            } else if (!@mkdir($dir, 0755)) {
                return $this->debug('Can\'t write in the target folder: '.$dir);
            }
        }

        clearstatcache();

        return is_dir($target);
    }
}

?>
